package com.chezai.client.activitys;

import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.RectF;
import android.hardware.Camera;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.TextView;

import com.baidu.aip.face.FaceRoundView;
import com.baidu.idl.face.platform.ui.utils.CameraUtils;
import com.baidu.idl.face.platform.utils.CameraPreviewUtils;
import com.chezai.client.R;
import com.chezai.client.bean.TakePhotoEntity;
import com.chezai.client.global.Const;
import com.chezai.client.inter.ICamera2View;
import com.chezai.client.presenter.Camera2Presenter;
import com.chezai.client.utils.CameraMgr;
import com.chezai.client.utils.DateUtil;
import com.chezai.client.utils.DialogUtils;
import com.chezai.client.utils.PreferenceManager;
import com.chezai.client.utils.SDCardUtil;
import com.chezai.client.utils.ToastUtil;
import com.chezai.client.widget.FaceView;

import org.greenrobot.eventbus.EventBus;

import butterknife.BindView;

/**
 * LYT 设备学员签到签退 拍照页
 * Created by likunyang on 2018/2/6.
 */

public class C703BCameraActivity extends BaseActivity<Camera2Presenter, ICamera2View> implements ICamera2View, Camera.FaceDetectionListener, Camera2Presenter.OnDetectFaceListener, SurfaceHolder.Callback, Camera.ErrorCallback, Camera.PictureCallback {
    public boolean isOpenVerity;
    public int mPhotoEventType;
    public int trainPart;
    public String studentName;
    public String coachName;
    public long mClassRecordId;
    public String uid;
    public String photoPath;
    public SurfaceHolder mSurfaceHolder;
    @BindView(R.id.surfaceView)
    SurfaceView mSurfaceView;
    @BindView(R.id.faceView)
    FaceView mFaceView;
    @BindView(R.id.face_round_view)
    FaceRoundView faceRoundView;
    @BindView(R.id.tv_hint)
    TextView tvHint;
    private boolean mFaceDetectionRunning = false;
    private volatile boolean isDetect;
    private Bitmap bitmap;
    private int mRetryCount;
    private boolean isTakeSucess;
    private Bitmap tempBitmap;
    private Camera mCamera;
    private Handler mHandler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            switch (msg.what) {
                case Const.CAMERA_HAS_STARTED_PREVIEW:
                    mFaceView.setPreviewViewRect(faceRoundView.getFaceRoundRect());
                    startFaceDetection();
                    break;
            }
            return false;
        }
    });
    private Camera.Parameters mCameraParam;
    private int mDisplayWidth;
    private int mDisplayHeight;

    @Override
    public int getLayoutId() {
        return R.layout.activity_c703b;
    }

    @Override
    public void initView(Bundle savedInstanceState) {
        getDisplay();
        mFaceView.isMirror(Const.CameraChannel.FONT);
        initSurfaceView();

        // harisucici 人脸提示关闭
        tvHint.setVisibility(View.INVISIBLE);

    }

    @Override
    public void initData() {
        isOpenVerity = PreferenceManager.getBoolean(Const.SP_IS_OPEN_VERITY, false);
//        isOpenVerity = true;// harisucici 人脸 打开试试
        Intent intent = getIntent();
        mPhotoEventType = intent.getIntExtra(Const.EVENT_PHOTO_TYPE, 0);
        trainPart = intent.getIntExtra(Const.TRAIN_PART, 0);
        if (intent.hasExtra(Const.STUDENT_NAME)) {
            studentName = intent.getStringExtra(Const.STUDENT_NAME);
        }
        if (intent.hasExtra(Const.COACH_NAME)) {
            coachName = intent.getStringExtra(Const.COACH_NAME);
        }
        if (intent.hasExtra(Const.CLASS_RECORD_ID)) {
            mClassRecordId = intent.getLongExtra(Const.CLASS_RECORD_ID, -1);
        }
        uid = intent.getStringExtra(Const.STUDENT_UID);
        photoPath = SDCardUtil.getStudentPhotoPath();
    }

    private void getDisplay() {
        DisplayMetrics dm = new DisplayMetrics();
        Display display = this.getWindowManager().getDefaultDisplay();
        display.getMetrics(dm);
        mDisplayWidth = dm.widthPixels;
        mDisplayHeight = dm.heightPixels;
    }

    @Override
    public void setListener() {
        presenter.setOnDetectFaceListener(this);
    }

    private void initSurfaceView() {
        mSurfaceHolder = mSurfaceView.getHolder();
        mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        mSurfaceHolder.addCallback(this);
    }

    private void setCameraParameter() {
        if (mCamera == null) {
            return;
        }
        mCamera.setAnalogInputState(true, Camera.INTERFACE_CVBS, Camera.SYSTEM_PAL, Camera.CHANNEL_ONLY_1, Camera.FORMAT_PL_420);
        mCamera.setAnalogInputColor(50, 50, 50, 50);
        if (mCameraParam == null) {
            mCameraParam = mCamera.getParameters();
        }
        mCameraParam.setPictureFormat(PixelFormat.JPEG);
        int degree = CameraMgr.displayOrientation(Camera.CameraInfo.CAMERA_FACING_FRONT, this);
        mCamera.setDisplayOrientation(degree);
        // 设置后无效，camera.setDisplayOrientation方法有效
        mCameraParam.set("rotation", degree);
        Point point = CameraPreviewUtils.getBestPreview(mCameraParam, new Point(mDisplayWidth, mDisplayHeight));
        mCameraParam.setPreviewSize(point.x, point.y);
        mCameraParam.setPictureSize(640, 480);
        mCamera.setParameters(mCameraParam);
    }


    @Override
    public void surfaceCreated(SurfaceHolder surfaceHolder) {

    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int i, int width, int height) {
        if (holder.getSurface() == null) {
            return;
        }
        openCamera();
        setCameraParameter();
        startPreviewView();
        mHandler.sendEmptyMessageDelayed(Const.CAMERA_HAS_STARTED_PREVIEW, 1000);
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
        stopFaceDetection();
        stopPreviewView();
    }

    public void openCamera() {
        if (mCamera == null) {
            try {
                mCamera = Camera.open(Const.CameraChannel.FONT);
            } catch (Exception e) {
                e.printStackTrace();
                showToast("打开相机失败!" + e.getMessage());
                finish();
            }
        }
    }

    public void startPreviewView() {
        try {
            mCamera.setPreviewDisplay(mSurfaceHolder);
            mCamera.stopPreview();
            mCamera.setErrorCallback(this);
            mCamera.startPreview();
        } catch (RuntimeException e) {
            e.printStackTrace();
            CameraUtils.releaseCamera(mCamera);
            mCamera = null;
        } catch (Exception e) {
            e.printStackTrace();
            CameraUtils.releaseCamera(mCamera);
            mCamera = null;
        }
    }

    public void stopPreviewView() {
        cameraRelease();
        if (mSurfaceHolder != null) {
            mSurfaceHolder.removeCallback(this);
        }
    }

    public void cameraRelease() {
        if (mCamera != null) {
            try {
                mCamera.setErrorCallback(null);
                mCamera.setPreviewCallback(null);
                mCamera.stopPreview();
            } catch (RuntimeException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                CameraUtils.releaseCamera(mCamera);
                mCamera = null;
            }
        }
    }

    /**
     * 开始人脸检测
     */
    private void startFaceDetection() {
        if (mCamera != null && mCamera.getParameters().getMaxNumDetectedFaces() > 0) {
            mCamera.setFaceDetectionListener(this);
            mCamera.startFaceDetection();
            mFaceDetectionRunning = true;
        }
    }

    private void stopFaceDetection() {
        if (mFaceDetectionRunning) {
            mCamera.setFaceDetectionListener(null);
            mCamera.stopFaceDetection();
            mFaceDetectionRunning = false;
        }
    }

    @Override
    public void onFaceDetection(Camera.Face[] faces, Camera camera) {
        if (isDetect) {
            return;
        }
        if (mFaceView != null && faces != null) {
            if (faces.length < 1) {
                tvHint.setText(R.string.detect_no_face);
            } else {
                RectF faceRect = mFaceView.getFaceRect(faces[0]);
                int status = mFaceView.compareRect(faceRect);
                switch (status) {
                    case FaceView.FACE_DETECT_LEFT:
                        tvHint.setText("向左移动");
                        faceRoundView.processDrawState(true);
                        break;
                    case FaceView.FACE_DETECT_TOP:
                        tvHint.setText("向下移动");
                        faceRoundView.processDrawState(true);
                        break;
                    case FaceView.FACE_DETECT_RIGHT:
                        tvHint.setText("向右移动");
                        faceRoundView.processDrawState(true);
                        break;
                    case FaceView.FACE_DETECT_BOTTOM:
                        tvHint.setText("向上移动");
                        faceRoundView.processDrawState(true);
                        break;
                    case FaceView.FACE_DETECT_OUT:
                        tvHint.setText("把脸移入框内");
                        faceRoundView.processDrawState(true);
                        break;
                    case FaceView.FACE_DETECT_GOOD:
                        tvHint.setText("很好");
                        faceRoundView.processDrawState(false);
                        isDetect = true;
                        stopFaceDetection();
                        takePhoto();
                        break;
                }
            }
        }
    }

    public void takePhoto() {
        if (mCamera != null) {
            mCamera.takePicture(null, null, this);
        }
    }

    @Override
    public void onPictureTaken(byte[] data, Camera camera) {
        bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
        bitmap = CameraMgr.onWaterDraw(bitmap, trainPart, studentName, coachName,System.currentTimeMillis());
        isTakeSucess = CameraMgr.saveBitmapToFile(bitmap, photoPath);
        mCamera.stopPreview();
        stopFaceDetection();
       DialogUtils.showProgressBarDialog(this, "照片处理中...");
        if (isOpenVerity){
            presenter.detect(photoPath);
        }else{
            verifySucess();
        }
    }

    @Override
    public void detectFace(Bitmap bitmap) {
        tempBitmap = bitmap;
        if (isOpenVerity) {
            presenter.upload(bitmap, uid);
        } else {
            verifySucess();
        }
    }

    @Override
    public void detectFaceError() {
       DialogUtils.dismissDialog();
        showToast("未找到人脸或照片不清晰，请重试");
        isDetect = false;
        mCamera.startPreview();
        startFaceDetection();
    }

    @Override
    public void finishView() {
        finish();
    }

    @Override
    public void verifySucess() {
       DialogUtils.dismissDialog();
        TakePhotoEntity takePhoto = new TakePhotoEntity();
        if (isTakeSucess) {
            takePhoto.status = TakePhotoEntity.TAKE_PHOTO_SUCESS;
            takePhoto.classRecordId = mClassRecordId;
            takePhoto.photoPath = photoPath;
            takePhoto.photoEventType = mPhotoEventType;
        } else {
            takePhoto.status = TakePhotoEntity.TAKE_PHOTO_FAILE;
        }
        EventBus.getDefault().postSticky(takePhoto);
        finish();
    }

    @Override
    public void verifyFailed(int errorCode) {
        if (errorCode == Camera2Presenter.VERIFY_ERROR_DEFAULT) {
            presenter.deletePhoto(photoPath);
            finish();
        } else if (errorCode == Camera2Presenter.VERIFY_ERROR_LOW) {
            if (mRetryCount >= 4) {
                ToastUtil.showLongToast(this, "重试次数已达上限,稍后重试");
                presenter.deletePhoto(photoPath);
                finish();
                return;
            }
            mRetryCount++;
            mCamera.startPreview();
            startFaceDetection();
            isDetect = false;
        }
    }

    @Override
    public void getAccessToken() {
        if (isOpenVerity && tempBitmap != null) {
            presenter.upload(tempBitmap, uid);
        } else {
            verifySucess();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (tempBitmap != null) {
            tempBitmap.recycle();
            tempBitmap = null;
        }
    }

    @Override
    public void onError(int error, Camera camera) {
        showToast("摄像头启动失败，请重试！");
        finish();
    }
}
